#include "Material.h"
#include "NeroCore\NMemoryManager.h"
#include "ShaderResourceManager.h"
#include "Shader.h"

using namespace Graphics;

RTTI_DEFINITIONS(Material)

#ifdef DX_11

Material::Material(const std::string& instanceName, const std::string& filePath)
	:Engine::NResource(instanceName,filePath)
{
}

Material::~Material(void)
{
}

void Material::Initialize()
{
}

void Material::SetShader(Shader* shader)
{
	mShader = shader;
}

void Material::Update(Graphics::RenderableEntity* entity)
{
}

void Material::Render(Graphics::RenderableEntity* entity)
{
}

#endif
#ifdef DX_9

Material::Material(const std::string& instanceName, const std::string& filePath)
	:Engine::NResource(instanceName,filePath)
{
}

Material::~Material(void)
{
	ParameterList::iterator it = mParameters.begin();
	for(;it != mParameters.end();++it)
	{
		ShaderParameter* parameter = (*it).second;
		if(parameter != NULL)
		{
			MY_DELETE(parameter);
			(*it).second = NULL;
		}
	}
}

void Material::Initialize()
{
}

void Material::SetShader(Shader* shader)
{
	mShader = shader;
}

ShaderParameter* Material::operator[](const char* parameterName)
{
	ParameterList::iterator it = mParameters.find(parameterName);
	if(it == mParameters.end())
	{
		return NULL;
	}
	return mParameters[parameterName];	
}

void Material::SetParameter(ShaderParameter* effectParameter, void* value)
{
	if(value == NULL)
	{
		return;
	}

	UINT size = 0;
	switch(effectParameter->GetDescription().Class)
	{
		case D3DXPC_SCALAR:
			switch(effectParameter->GetDescription().Type)
			{
				case D3DXPT_BOOL:
					mShader->GetEffect()->SetBoolArray(effectParameter->GetHandle(),(BOOL*)value,size);
					break;
				case D3DXPT_INT:
					mShader->GetEffect()->SetIntArray(effectParameter->GetHandle(),(INT*)value,size);
					break;
				case D3DXPT_FLOAT:
					mShader->GetEffect()->SetFloatArray(effectParameter->GetHandle(),(FLOAT*)value,size);
					break;
				case D3DXPT_STRING:
					mShader->GetEffect()->SetString(effectParameter->GetHandle(),(char*)value);
					break;
			}
		case D3DXPC_MATRIX_ROWS:
		case D3DXPC_MATRIX_COLUMNS:
			size = effectParameter->GetDescription().Elements;
			mShader->GetEffect()->SetMatrix(effectParameter->GetHandle(),(D3DXMATRIX*)value);
			break;
		case D3DXPC_VECTOR:
			size = effectParameter->GetDescription().Columns;
			mShader->GetEffect()->SetVector(effectParameter->GetHandle(),(D3DXVECTOR4*)value);
			break;
		case D3DXPC_OBJECT:
			mShader->GetEffect()->SetTexture(effectParameter->GetHandle(),(LPDIRECT3DBASETEXTURE9)value);
			break;
		default:
			//throw RendException("Win32Material::SetParameter::Type Not Supported",__FILE__,__LINE__);
		return;
	}

	effectParameter->SetValue(value);
}

void Material::Update(Graphics::RenderableEntity* entity)
{

}

void Material::Render(Graphics::RenderableEntity* entity)
{

}
#endif